import base64
import json
import pickle

from django import http
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import Commodity


class CartsView(View):
    def get(self, request):
        """展示购物车"""
        user = request.user
        if user.is_authenticated:
            # 用户已登录，查询redis购物车
            redis_conn = get_redis_connection('carts')
            # 获取redis中的购物车数据
            redis_cart = redis_conn.hgetall('carts_%s' % user.id)
            # 获取redis中的选中状态
            cart_selected = redis_conn.smembers('selected_%s' % user.id)

            # 将redis中的数据构造成跟cookie中的格式一致，方便统一查询
            cart_dict = {}
            for sku_id, count in redis_cart.items():
                cart_dict[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in cart_selected
                }
            # 构造购物车渲染数据
            sku_ids = cart_dict.keys()
            skus = Commodity.objects.filter(id__in=sku_ids)

            # print(cart_dict.get(sku_id).get('count'))
            cart_skus = []
            for sku in skus:
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'unit': sku.unit,  # 单位 500g
                    'count': cart_dict.get(sku.id).get('count'),  # 数量
                    # 'count': cart_dict[str(sku.id)].get('count'),  # 数量
                    'selected': str(cart_dict.get(sku.id).get('selected')),  # 将True，转'True'，方便json解析
                    # 'selected': str(cart_dict[str(sku.id)].get('selected')),  # 将True，转'True'，方便json解析
                    'default_image_url': sku.image1,  # 图片
                    'price': str(sku.price),  # 价格
                    'amount': str(sku.price * cart_dict.get(sku.id).get('count')),  # 总价
                    # 'amount': str(sku.price * cart_dict[str(sku.id)].get('count')),  # 总价
                })

            context = {
                'cart_skus': cart_skus,
            }
            print(context['cart_skus'])

            # 渲染购物车页面
            return render(request, 'cart.html', context)
        else:
            # 用户未登录，查询cookies购物车
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}
            # 构造购物车渲染数据
            sku_ids = cart_dict.keys()
            skus = Commodity.objects.filter(id__in=sku_ids)

            # print(cart_dict.get(sku_id).get('count'))
            cart_skus = []
            for sku in skus:
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'unit': sku.unit,  # 单位 500g
                    # 'count': cart_dict.get(sku.id).get('count'),  # 数量
                    'count': cart_dict[str(sku.id)].get('count'),  # 数量
                    # 'count': cart_dict.get(sku.id)['count'],  # 数量
                    # 'selected': str(cart_dict.get(sku.id).get('selected')),  # 将True，转'True'，方便json解析
                    'selected': str(cart_dict[str(sku.id)].get('selected')),  # 将True，转'True'，方便json解析
                    'default_image_url': sku.image1,  # 图片
                    'price': str(sku.price),  # 价格
                    # 'amount': str(sku.price * cart_dict.get(sku.id).get('count')),  # 总价
                    'amount': str(sku.price * cart_dict[str(sku.id)].get('count')),  # 总价
                })

            context = {
                'cart_skus': cart_skus,
            }
            print(context['cart_skus'])

            # 渲染购物车页面
            return render(request, 'cart.html', context)

    # def get(self, request):
    #     """展示购物车"""
    #     user = request.user
    #     if user.is_authenticated:
    #         # 用户已登录，查询redis购物车
    #         redis_conn = get_redis_connection('carts')
    #         # 获取redis中的购物车数据
    #         redis_cart = redis_conn.hgetall('carts_%s' % user.id)
    #         # 获取redis中的选中状态
    #         cart_selected = redis_conn.smembers('selected_%s' % user.id)
    #
    #         # 将redis中的数据构造成跟cookie中的格式一致，方便统一查询
    #         cart_dict = {}
    #         for sku_id, count in redis_cart.items():
    #             cart_dict[int(sku_id)] = {
    #                 'count': int(count),
    #                 'selected': sku_id in cart_selected
    #             }
    #
    #     else:
    #         # 用户未登录，查询cookies购物车
    #         cart_str = request.COOKIES.get('carts')
    #         if cart_str:
    #             # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
    #             cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
    #         else:
    #             cart_dict = {}
    #     # 构造购物车渲染数据
    #     sku_ids = cart_dict.keys()
    #     skus = Commodity.objects.filter(id__in=sku_ids)
    #
    #     # print(cart_dict.get(sku_id).get('count'))
    #     cart_skus = []
    #     for sku in skus:
    #
    #         cart_skus.append({
    #             'id': sku.id,
    #             'name': sku.name,
    #             'unit': sku.unit,  # 单位 500g
    #             'count': cart_dict.get(sku.id).get('count'),  # 数量
    #             # 'count': cart_dict[str(sku.id)].get('count'),  # 数量
    #             # 'count': cart_dict.get(sku.id)['count'],  # 数量
    #             'selected': str(cart_dict.get(sku.id).get('selected')),  # 将True，转'True'，方便json解析
    #             # 'selected': str(cart_dict[str(sku.id)].get('selected')),  # 将True，转'True'，方便json解析
    #             'default_image_url': sku.image1,  # 图片
    #             'price': str(sku.price),  # 价格
    #             'amount': str(sku.price * cart_dict.get(sku.id).get('count')),  # 总价
    #             # 'amount': str(sku.price * cart_dict[str(sku.id)].get('count')),  # 总价
    #         })
    #
    #     context = {
    #         'cart_skus': cart_skus,
    #     }
    #     print(context['cart_skus'])
    #
    #     # 渲染购物车页面
    #     return render(request, 'cart.html', context)

    def post(self, request):
        num = request.POST.get('num')
        sku_id = request.POST.get('sku')
        selected = True

        # print(price, num, sku_id)
        try:
            Commodity.objects.get(id=sku_id)
        except Commodity.DoesNotExist:
            return http.HttpResponseBadRequest('商品不存在')
            # 判断count是否为数字
        try:
            count = int(num)
        except Exception:
            return http.HttpResponseBadRequest('参数count有误')
            # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            # 用户已登录，操作redis购物车
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            # 新增购物车数据
            pl.hincrby('carts_%s' % user.id, sku_id, count)
            # 新增选中的状态
            if selected:
                pl.sadd('selected_%s' % user.id, sku_id)
            # 执行管道
            pl.execute()
            # 响应结果
            return JsonResponse({'code_s': 'OK', 'errmsg': '添加购物车成功'})
        else:
            # 用户未登录，操作cookie购物车
            cart_str = request.COOKIES.get('carts')
            # 如果用户操作过cookie购物车
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:  # 用户从没有操作过cookie购物车
                cart_dict = {}

            # 判断要加入购物车的商品是否已经在购物车中,如有相同商品，累加求和，反之，直接赋值
            if sku_id in cart_dict:
                # 累加求和
                origin_count = cart_dict[sku_id]['count']
                count += origin_count
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            # print(cart_dict)
            # print(cart_dict.get(sku_id).get('count'))
            # 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
            cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()

            # 创建响应对象
            response = http.JsonResponse({'code': 'OK', 'errmsg': '添加购物车成功'})
            # 响应结果并将购物车数据写入到cookie
            response.set_cookie('carts', cookie_cart_str, max_age=3600)
            return response
